<?php
namespace App\Controllers\Sms;

use App\Controllers\BaseController;
use App\Library\Helper;
use App\Library\SmsGateway\Adapter as SmsAdapter;
use App\Models\SmsMtTestLoger;
use App\Models\SmsMtTestTempQueue;

class TController extends BaseController {

    public function initialize() {
        parent::initialize();
    }

    public function indexAction() {
    }

    //-------------------------------------------------------------------------
    // 下发验证码短信
    //-------------------------------------------------------------------------
    public function mtAction() {
        $this->send('captcha');
    }

    //-------------------------------------------------------------------------
    // 下发短信实际执行函数
    //-------------------------------------------------------------------------
    private function send($act) {
        $config    = $this->getDI()->get('globalConfig');
        $whiteList = $config->SmsWhiteList->toArray();
        $gateways  = $config->SmsGateways->toArray();
        $receiveAt = Helper::getNow();
        $mobile    = trim(isset($_GET['mobile']) ? trim($_GET['mobile']) : (isset($_POST['mobile']) ? $_POST['mobile'] : ''));
        $content   = trim(isset($_GET['content']) ? trim($_GET['content']) : (isset($_POST['content']) ? $_POST['content'] : ''));
        $ip        = $this->request->getServer("REMOTE_ADDR");
        $param = $this->dispatcher->getParam(0);
        if(!$param) {
            $gateway = $config->SmsTestTriggerGateway;
        } else {
            $param   = strtolower($param);
            $gateway = in_array($param, $gateways) ? $param : $config->SmsTriggerGateway;
        }
        if($gateway == 'daredo' && $act == 'notice') {
            $gateway = 'daredo2';
        }
        //无论什么情况,都走测试的网关
        $gateway = $config->SmsTestTriggerGateway;
        $result  = [
            'action'      => $act,
            'mobile'      => $mobile,
            'mt'          => $content,
            'receive_at'  => $receiveAt,
            'ip'          => $ip,
            'fee_count'   => 0,
            'send_at'     => null,
            'status_msg'  => '',
            'gateway'     => $gateway,
            'gateway_msg' => '',
        ];
        //判断请求是不是在白名单里
        if(isset($whiteList) && !in_array($ip, $whiteList)) {
            $result = array_merge($result, [
                'status'     => SmsAdapter::ERROR_IP,
                'status_msg' => SmsAdapter::ERROR_IP_MESSAGE,
                'is_fee'     => -1,
            ]);
            $this->loger($result);
            return $this->output($result);
        }
        //判断内容是不是为空
        if($content == '') {
            $result = array_merge($result, [
                'status'     => SmsAdapter::ERROR_MT_EMPTY,
                'status_msg' => SmsAdapter::ERROR_MT_EMPTY_MESSAGE,
                'is_fee'     => -1,
            ]);
            $this->loger($result);
            return $this->output($result);
        }
        $content = urldecode($content);
        /*
        $upContent = strtoupper($content);
        if(mb_strpos($upContent, '回复TD退订', 0, 'utf-8') === false) {
            $content = str_replace('【美赞臣】', '', $content);
            $content = $content . '回复TD退订';
        }
        if(mb_strpos($upContent, '【美赞臣】', 0, 'utf-8') === false) {
            $content = $content . '【美赞臣】';
        }*/
        $content = str_replace(['A 妈妈会'], ['A+妈妈会'], $content);

        $result['mt'] = $content;
        //判断是不是手机号码
        if(!Helper::isMobile($mobile)) {
            $result = array_merge($result, [
                'status'     => SmsAdapter::ERROR_MOBILE,
                'status_msg' => SmsAdapter::ERROR_MOBILE_MESSAGE,
                'is_fee'     => -1,
            ]);
            $this->loger($result);
            return $this->output($result);
        }

        $mtLength = mb_strlen($content, 'utf-8');
        if($mtLength <= 70) {
            $feeCount = 1;
        } else {
            $feeCount = ceil($mtLength / 68);
        }
        $queue = new SmsMtTestTempQueue();
        //从内存表中读取
        $queueLogs = $queue->gets($mobile);
        //初始一个是否此次短信被拒绝的结果
        $retQueueChecker = [];
        if(is_array($queueLogs) && count($queueLogs) > 0) {
            //当天发送的总数
            if(count($queueLogs) >= 5) {
                $retQueueChecker = [
                    'status'      => SmsAdapter::ERROR_SEND_MAX,
                    'status_msg'  => SmsAdapter::ERROR_SEND_MAX_MESSAGE,
                    'gateway_msg' => '',
                    'send_at'     => $receiveAt
                ];
            }
            //发送失败，发送的间隔不能小于60秒！
            if(count($retQueueChecker) == 0 && isset($queueLogs[0]) && isset($queueLogs[0]['receive_at'])) {
                $last = strtotime($queueLogs[0]['receive_at']);
                if((time() - $last) < 60) {
                    $retQueueChecker = [
                        'status'      => SmsAdapter::ERROR_SEND_INTERVAL_TIME_ERROR,
                        'status_msg'  => SmsAdapter::ERROR_SEND_INTERVAL_TIME_ERROR_MESSAGE,
                        'gateway_msg' => '',
                        'send_at'     => $receiveAt
                    ];
                }
            }
            //发送失败，半小时内只允许发送3条！
            if(count($retQueueChecker) == 0 && isset($queueLogs[2]) && isset($queueLogs[2]['receive_at'])) {
                //$last1 = strtotime($logs[0]['send_at']);//倒数第一条
                //$last2 = strtotime($logs[1]['send_at']);//倒数第二条
                $last = strtotime($queueLogs[2]['receive_at']);//倒数第三条
                $now  = time();
                if(($now - $last) < 60 * 30) {
                    $retQueueChecker = [
                        'status'      => SmsAdapter::ERROR_SEND_HALF_HOUR_LIMIT_ERROR,
                        'status_msg'  => SmsAdapter::ERROR_SEND_HALF_HOUR_LIMIT_ERROR_MESSAGE,
                        'gateway_msg' => '',
                        'send_at'     => $receiveAt
                    ];
                }
            }
        }
        if(empty($retQueueChecker)) {
            //能够正常发送的,记录到lock内存表,方便下次判断
            $queue->add($mobile);
        }
        //如果能够正常发送,调用发送短信模块发送短信
        if(count($retQueueChecker) == 0) {
            $adapter = new SmsAdapter();
            $adapter->loadDriver($gateway);
            $retGateway = $adapter->mt($mobile, $content);
            $result     = array_merge($result, $retGateway);
            if($retGateway['status'] == SmsAdapter::SUCCESS) {
                $result = array_merge($result, [
                    'mt_length' => $mtLength,
                    'fee_count' => $feeCount,
                    'is_fee'    => 1,
                ]);
            } else {
                $result = array_merge($result, [
                    'mt_length' => $mtLength,
                    'fee_count' => $feeCount,
                    'is_fee'    => 1,
                ]);
            }
        } else {
            $result = array_merge($result, $retQueueChecker, [
                'mt_length' => $mtLength,
                'fee_count' => $feeCount,
                'is_fee'    => 1,
            ]);
        }

        $this->loger($result);
        $this->output($result);
    }

    private function output($result) {
        if($result['send_at'] == null) {
            $result['send_at'] = '';
        }
        $result['message'] = $result['status_msg'];
        unset($result['is_fee']);
        unset($result['gateway']);
        unset($result['gateway_msg']);
        unset($result['status_msg']);
        ksort($result);
        return $this->json($result);
    }

    private function loger($retSend) {
        $retSend['create_at'] = Helper::getNow();

        $model = new SmsMtTestLoger();
        $model->add($retSend);
    }
}
